<template>
  <div class="w-full">
    <template v-if="type === 'image'">
      <a-upload
        :file-list="fileList"
        list-type="picture-card"
        accept=".jpg, .jpeg, .png, .gif"
        :action="uploadImage()"
        :headers="{ Authorization: token }"
        :multiple="false"
        :limit="1"
        name="file"
        image-preview
        @success="handleUploadSuccess"
        @error="handleUploadError"
        :on-before-remove="onBeforeRemove"
        @before-upload="beforeUpload"
        draggable
      />
    </template>
    <template v-else>
      <a-upload
        draggable
        :file-list="fileList"
        :show-file-list="false"
        :action="uploadImage()"
        :headers="{ Authorization: token }"
        name="file"
        @success="handleUploadSuccess"
        @error="handleUploadError"
        @change="onChange"
      >
        <template #upload-button>
          <div
            style="
              background-color: var(--color-fill-2);
              color: var(--color-text-1);
              border: 1px dashed var(--color-fill-4);
            "
            class="flex-col-center w-32n h-25n m-relative"
            v-if="!realFileList.length"
          >
            <template v-if="videoFile.percent == 0">
              <icon-plus class="mb-10" />
              <div>拖拽或点击上传</div>
            </template>
            <template v-else>
              <a-spin tip="上传中" :size="28" />
            </template>
          </div>
          <div v-else class="m-relative box">
            <div class="mask flex-center" @click.stop="onRemoveVideo">
              <icon-delete class="textfff text-size-20" />
            </div>
            <video width="150" autoplay loop muted :src="realFileList[0].url">您的浏览器不支持此种视频格式。</video>
          </div>
        </template>
      </a-upload>
    </template>
    <div class="text999 text-size-13 mt-10" v-if="placeholder">{{ placeholder }}</div>
  </div>
</template>

<script setup>
// 使用示例
import { uploadImage } from '@/apis'
import { getToken } from '@/utils/auth'
import { Message } from '@arco-design/web-vue'
import { v4 } from 'uuid'
defineOptions({ name: 'MsUpload' })
const emit = defineEmits(['update:modelValue', 'getWH'])

const props = defineProps({
  action: {
    default: '',
    type: String
  },
  type: {
    default: 'image',
    type: String
  },
  modelValue: {
    default: '',
    type: String
  },
  placeholder: {
    default: '',
    type: String
  },
  limitW: {
    default: 0,
    type: Number
  },
  limitH: {
    default: 0,
    type: Number
  }
})

// 上传组件需要增加token
const tokenSource = getToken()
const token = tokenSource ? `Bearer ${tokenSource}` : ''
const fileList = ref([])
const realFileList = ref() //真实的上传列表
const videoFile = ref({
  status: '',
  percent: 0
})

watch(
  () => props.modelValue,
  (str) => {
    if (str) {
      const id = v4()
      fileList.value = [
        {
          uid: id,
          name: `${id}.png`,
          url: str
        }
      ]
      videoFile.value.percent = 1
    } else {
      videoFile.value.percent = 0
      fileList.value = []
    }
    realFileList.value = {
      ...realFileList.value,
      url: str
    }
  },
  { deep: true, immediate: true }
)

// 上传图片成功改变
const handleUploadSuccess = (fileItem) => {
  if (fileItem.response.code != 200) return Message.error(fileItem.response.message)
  else {
    realFileList.value = {
      uid: fileItem.uid,
      name: fileItem.name,
      url: fileItem.response.data.url || fileItem.response.data.videoLink,
      width: fileItem.response.data.imageWidth,
      height: fileItem.response.data.imageHeight
    }
    emit('getWH', {
      width: fileItem.response.data.imageWidth,
      height: fileItem.response.data.imageHeight
    })
  }
}

// 上传失败
const handleUploadError = (e) => {
  Message.error(e.response.message)
}

// 移除已上传图片
const onBeforeRemove = () => {
  return new Promise((resolve, reject) => {
    try {
      realFileList.value = null
      emit('getWH', {
        width: null,
        height: null
      })
      resolve(true)
    } catch {
      reject(false)
    }
  })
}

const onRemoveVideo = () => {
  realFileList.value = null
  fileList.value = []
  videoFile.value.status = ''
  videoFile.value.percent = 0
}

// 监听真正的上传列表以改变同步数值
watch(
  () => realFileList.value,
  (value) => {
    emit('update:modelValue', value?.url)
    // emit('getWH', {
    //   width: value?.width,
    //   height: value?.height
    // })
  },
  {
    deep: true,
    immediate: true
  }
)

const onChange = (_, currentFile) => {
  videoFile.value = {
    ...currentFile
  }
}

const beforeUpload = (file) => {
  return new Promise((resolve, reject) => {
    let _URL = window.URL || window.webkitURL
    let image = new Image()
    image.onload = function () {
      let w = this.width
      let h = this.height
      if (props.limitW && w > props.limitW) {
        Message.error('最大宽度为' + props.limitW + 'px,现在是' + w + 'px')
        reject('cancel')
      } else if (props.limitH && h > props.limitH) {
        Message.error('最大高度为' + props.limitW + 'px,现在是' + w + 'px')
        reject('cancel')
      } else resolve(true)
    }
    image.src = _URL.createObjectURL(file)
  })
}
</script>

<style scoped lang="scss">
.mask {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(25, 25, 25, 0.6);
  display: flex;
  z-index: 2;
  align-items: center;
  justify-content: center;
  opacity: 0;
}
.box:hover .mask {
  opacity: 1;
}

:deep(.arco-upload-list-picture img) {
  object-fit: contain !important;
}
:deep(.arco-upload-wrapper-type-picture-card) {
  width: 100%;
}
:deep(.arco-upload-list-type-picture-card) {
  width: 100%;
  img {
    object-fit: scale-down !important;
  }
}
:deep(.arco-upload.arco-upload-draggable) {
  width: auto;
}

:deep(.arco-upload-list-picture) {
  background-color: #fafafa;
  border: 1px dashed #d9d9d9;
  padding: 8px;
  height: auto;
  width: auto;
  min-height: 100px;
  min-width: 100px;
  max-width: 200px;
  max-height: 200px;
}
:deep(.arco-upload-list-picture-mask) {
  /* line-height: 100px;*/
  display: flex;
  z-index: 2;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
  -webkit-box-pack: center;
  -ms-flex-pack: center;
  justify-content: center;
}
:deep(.arco-upload-icon-preview) {
  margin-right: 14px;
}
:deep(.arco-upload-list-picture-operation),
:deep(.arco-upload-icon-remove) {
  font-size: 20px;
}
</style>
